{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# iSWAP 门\n",
    "\n",
    "*版权所有 (c) 2021 百度量子计算研究所，保留所有权利。*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 内容概要\n",
    "本教程将演示如何使用量脉生成 iSWAP 门的优化脉冲，本教程的大纲如下：\n",
    "- 背景介绍\n",
    "- 准备工作\n",
    "- 构造哈密顿量\n",
    "- 通过量脉云服务生成与优化脉冲\n",
    "- 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 背景介绍\n",
    "iSWAP 门是超导量子计算中的一个原生门，因为它可以通过两个超导量子比特之间的耦合（XY 相互作用）直接实现。在超导电路中，iSWAP 门是通过将两个量子比特调谐到共振，并持续一段时间来实现的。iSWAP 门在两个量子比特之间交换激发态，并增加一个 $i$ 的相位 \\[1\\]。iSWAP 门的酉矩阵为：\n",
    "$$\n",
    "\\rm iSWAP = \\begin{pmatrix}\n",
    "    1 & 0 & 0 & 0 \\\\\n",
    "    0 & 0 & -i & 0 \\\\\n",
    "    0 & -i & 0 & 0 \\\\\n",
    "    0 & 0 & 0 & 1   \n",
    "\\end{pmatrix}.\n",
    "$$\n",
    "通过旋转波近似，量子比特间的耦合哈密顿量可以写成 \\[2\\]：\n",
    "$$\n",
    "\\hat H_{\\rm coup} = g(e^{i\\delta_{01}t}\\hat{a}_0^\\dagger\\hat{a}_1+e^{-i\\delta_{01}t}\\hat{a}_0\\hat{a}_1^\\dagger),\n",
    "$$\n",
    "其中 $\\delta_{12}=\\omega_{q1}-\\omega_{q2}$ 是两个量子比特间的失调（$\\omega _{qi}$ 是第 $i$ 个量子比特的频率）。通过调节量子比特 1 的磁通，使其与量子比特 2 共振，失调 $\\delta_{12}=0$。 $\\sigma_i^+$ 和 $\\sigma_i^-$是第 $i$ 个 qubit 的产生和湮灭算符。耦合哈密顿量简化为：\n",
    "$$\n",
    "\\hat H_{\\rm coup} = g(\\hat{a}_0^\\dagger\\hat{a}_1+\\hat{a}_0\\hat{\\sigma}_1^\\dagger),\n",
    "$$\n",
    "从表达式可以看出，这一项导致两个量子比特之间激发态的交换。\n",
    "\n",
    "此外，我们可以使用两个 iSWAP 门和几个单量子比特门来生成 CNOT 门。实验上，我们还可以利用 iSWAP 门产生 GHZ 态 \\[2\\]。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备工作\n",
    "成功安装量脉后，您可以按照本教程运行下面的量脉程序。要运行此教程，您需要从量脉（Quanlse）和其它常用的 Python 库导入以下的包："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import numpy and math constants\n",
    "from numpy import round\n",
    "from math import pi\n",
    "\n",
    "# Import the Hamiltonian module\n",
    "from Quanlse.QHamiltonian import QHamiltonian as QHam\n",
    "from Quanlse.QOperator import duff, number\n",
    "\n",
    "# Import Optimizer for ISWAP gate\n",
    "from Quanlse.remoteOptimizer import remoteOptimizeISWAP\n",
    "\n",
    "# Import tools for analysing results\n",
    "from Quanlse.Utils.Functions import project"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造哈密顿量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用量脉优化前，我们需要指定系统的哈密顿量。我们考虑引入每个量子比特的三个最低能级，其中第三能级代表了能级的泄漏。在旋转坐标系中，两个耦合量子比特的系统哈密顿量表示为 \\[1\\]：\n",
    "$$\n",
    "\\hat H =(\\omega_{q1}-\\omega_{d1})\\hat a^\\dagger_1 \\hat a_1+(\\omega_{q2}-\\omega_{d2})\\hat a^\\dagger_2 \\hat a_2+ \\frac{\\alpha _1}{2}\\hat a^\\dagger_1 \\hat a^\\dagger_1 \\hat a_1 \\hat a_1 + \\frac{\\alpha_2}{2}\\hat a^\\dagger_2 \\hat a^\\dagger_2 \\hat a_2 \\hat a_2 +\\frac{g}{2}(\\hat a_1\\hat a_2^\\dagger+\\hat a_1^\\dagger \\hat a_2) + \\sum_i\\frac{A^z_i(t)}{2}\\hat a^\\dagger_i \\hat a_i,\n",
    "$$\n",
    "其中 $\\hat a_i^\\dagger$ ($\\hat a_i$) 是第 $i$（$i=1,2$）个量子比特的产生（湮灭）算符；$\\omega _{qi}$ 是第 $i$ 个量子比特的频率；$\\alpha_i$ 是第 $i$ 个量子比特的失谐；$g$ 是两个量子比特的耦合强度。$A_i^z(t)$ 是施加到第 $i$ 个量子比特的磁通。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "量脉通过指定采样周期、门时间以及运行计算所需的其它参数来定义系统哈密顿量。量脉可以灵活地为任意量子门操作进行定制模拟，特别是那些涉及参数优化的过程。首先，我们定义几个参数来设置采样周期、量子比特数和系统的维度："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Sampling period\n",
    "dt = 1.0\n",
    "# number of qubits\n",
    "qubits = 2\n",
    "# System energy level\n",
    "level = 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后我们定义两个量子比特的频率、驱动频率和失谐性以及它们之间的耦合强度："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "qubitArgs = {\n",
    "    \"coupling\": 0.0277 * (2 * pi),  # Coupling of Q0 and Q1\n",
    "    \"qubit_freq0\": 5.805 * (2 * pi),  # Frequency of Q0\n",
    "    \"qubit_freq1\": 5.205 * (2 * pi),  # Frequency of Q1\n",
    "    \"drive_freq0\": 5.205 * (2 * pi),  # Drive frequency on Q0\n",
    "    \"drive_freq1\": 5.205 * (2 * pi),  # Drive frequency on Q1\n",
    "    \"qubit_anharm0\": -0.217 * (2 * pi),  # Anharmonicity of Q0\n",
    "    \"qubit_anharm1\": -0.226 * (2 * pi)  # Anharmonicity of Q1\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们使用 `QHamiltonian()` 函数创建一个空的哈密顿量的字典，并根据先前定义的参数向其中添加漂移项与耦合项：\n",
    "$$\n",
    "\\begin{align*}\n",
    "\\hat H_{\\rm drift} &= (\\omega_{q0}-\\omega_{d0})(\\hat a^\\dagger_0 \\hat a_0)+(\\omega_{q1}-\\omega_{d1})(\\hat a^\\dagger_1 \\hat a_1)+\\frac{\\alpha _0}{2}\\hat a^\\dagger_0 \\hat a^\\dagger_0 \\hat a_0 \\hat a_0 + \\frac{\\alpha_1}{2}\\hat a^\\dagger_1 \\hat a^\\dagger_1 \\hat a_1 \\hat a_1, \\\\\n",
    "\\hat H_{\\rm coup} &= \\frac{g}{2}(\\hat a_0\\hat a_1^\\dagger+\\hat a_0^\\dagger \\hat a_1).\n",
    "\\end{align*}\n",
    "$$\n",
    "\n",
    "在量脉的 `Operator` 模块中，我们提供了一些允许用户快速构造常用算符的工具。失谐项 $(\\omega_{\\rm q}-\\omega_{\\rm d})\\hat{a}^\\dagger\\hat{a}$ 和非谐项 $\\frac{\\alpha}{2}\\hat{a}^\\dagger\\hat{a}^\\dagger\\hat{a}\\hat{a}$ 可以分别使用 `Operator` 模块中的 `number(n)` 和 `duff(n)` 生成：这两个函数 `number(n)` 和 `duff(n)` 分别返回 $n\\times n$ 的粒子数算符和 Duffing 算符。耦合项的形式为 $\\frac{g}{2}(\\hat{a}_i^\\dagger\\hat{a}_j+\\hat{a}_i\\hat{a}_j^\\dagger)$，可以使用函数 `addCoupling()` 直接添加到哈密顿量中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create the Hamiltonian\n",
    "ham = QHam(qubits, level, dt)\n",
    "\n",
    "# Add the drift term(s)\n",
    "for qu in range(2):\n",
    "    # Add the detuning term(s)\n",
    "    ham.addDrift(number, qu, (qubitArgs[f\"qubit_freq{qu}\"] - qubitArgs[f\"drive_freq{qu}\"]))\n",
    "    # Add the anharmonicity term(s)\n",
    "    ham.addDrift(duff, qu, qubitArgs[f\"qubit_anharm{qu}\"] / 2)\n",
    "\n",
    "# Add coupling term\n",
    "ham.addCoupling([0, 1], qubitArgs[\"coupling\"] / 2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，量脉的优化函数会自动添加控制项：\n",
    "\n",
    "$$ \n",
    "\\hat{H}_{\\rm ctrl} = \\frac{A_0^z(t)}{2}\\hat{a}_0^\\dagger \\hat{a}_0, \n",
    "$$\n",
    "\n",
    "所以我们不需要手动添加这项。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "所有关于系统哈密顿量的有用信息都存储在 `ham` 中。在开始优化之前，通常我们会为振幅设置一个边界。您可能需要多次运行优化并逐渐缩小边界。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "aBound = (-5, 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 通过量脉云服务生成与优化脉冲"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在使用量脉云服务之前，我们需要登录 http://quantum-hub.baidu.com 获取 token 来访问云端。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import tools to get access to cloud service\n",
    "from Quanlse import Define\n",
    "\n",
    "# To use remoteOptimizerISWAP() on cloud, paste your token (a string) here\n",
    "Define.hubToken = ''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "基于前面的准备工作，我们接下来开始优化脉冲。函数 `remoteOptimizeISWAP()` 需要传入五个参数。其中，`tg` 指定门持续时间；当失真度小于 `targetInfidelity` 或迭代次数超过 `maxIter` 时，优化将终止并返回最小失真度和具有优化控制项的系统哈密顿量。我们可以通过调用 `qham.printWaves()` 绘制波形，并调用 `qham.getUnitary()` 获取演化酉矩阵。\n",
    "\n",
    "在本教程中，作为性能评估指标的门失真度被定义为 ${\\rm infid} = 1 - \\frac{1}{d}\\left|{\\rm Tr}\n",
    "[U^\\dagger_{\\rm goal}P(U)]\\right|$，其中 $d$ 是 $U_{\\rm goal}$ $(U_{\\rm goal} = {\\rm iSWAP})$ 的维度，$U$ 是三能级系统的酉演化。值得注意的是，$P(U)$ 是描述被投影到计算子空间的演化。我们首先运行该优化，然后计算投影演化 $P(U)$："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run the optimization\n",
    "gateJob, infidelity = remoteOptimizeISWAP(ham, aBound=aBound, tg=40, maxIter=3, targetInfidelity=0.005)\n",
    "\n",
    "# Print infidelity and the waveforms\n",
    "print(f\"minimum infidelity: {infidelity}\")\n",
    "gateJob.plot()\n",
    "\n",
    "# Print the projected evolution\n",
    "result = ham.simulate(job=gateJob)\n",
    "print(\"The projected evolution P(U):\\n\", round(project(result[0][\"unitary\"], qubits, level, 2), 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们可以看到脉冲的驱动强度在 3.8 左右。我们可以通过将边界缩小到（-4.0，-3.6）来搜索更好的保真度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "aBound = (-4.0, -3.6)\n",
    "# Run the optimization\n",
    "gateJob, infidelity = remoteOptimizeISWAP(ham, aBound, tg=40, maxIter=5, targetInfidelity=0.01)\n",
    "\n",
    "# Print infidelity and the waveforms\n",
    "print(f\"minimum infidelity: {infidelity}\")\n",
    "gateJob.plot()\n",
    "\n",
    "# Print the projected evolution \n",
    "result = ham.simulate(job=gateJob)\n",
    "print(\"The projected evolution P(U):\\n\", round(project(result[0][\"unitary\"], qubits, level, 2), 2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果希望进一步降低失真度，请尝试增大参数 `maxIter`。当用户提供一组合理的参数时，量脉通常可以找到高保真度的优化波形。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "本教程使用量脉对 iSWAP 门的脉冲进行优化。用户可以通过点击这个链接 [tutorial-iswap.ipynb](https://github.com/baidu/Quanlse/blob/main/Tutorial/CN/tutorial-iswap-cn.ipynb) 跳转到此 Jupyter Notebook 文档相应的 GitHub 页面，并且运行这个程序。我们鼓励用户尝试不同于本教程的参数值以获得最佳结果。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 参考文献\n",
    "\n",
    "\\[1\\] [Schuch, Norbert, and Jens Siewert. \"Natural two-qubit gate for quantum computation using the XY interaction.\" *Physical Review A* 67.3 (2003): 032301.](https://link.aps.org/doi/10.1103/PhysRevA.67.032301)\n",
    "\n",
    "\\[2\\] [Krantz, Philip, et al. \"A quantum engineer's guide to superconducting qubits.\" *Applied Physics Reviews* 6.2 (2019): 021318.](https://doi.org/10.1063/1.5089550)"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "6ad73c40f4f7e139e51b4243fd18c81784a68c09ce49361ba281b37d203f3e8e"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
